/* $RCSFile: BagHolder.cs $
 * Apache license v2 2011 by Christian Surieux
 * $Source: ?/ADNCRM.Core/BLL/Utils/BagHolder.cs $
 * $log$
 * Revision 6 2010/08/06 19:56:27  christian.surieux
 *   Added Log to All cs files
 */

	//===============================================================================
	//
	//	Business Logic Layer
	//
	//	AddonNice.BLL.Utils
	//
	// Classes to Manage the User Web Collection
    //
	//===============================================================================

namespace AddonNice.BLL.Utils
{

	using System;
	using System.Web;
	using System.Diagnostics;

	/// <summary>
	/// Define the Web Bag Interface as the
	/// repository for temporary data
	/// </summary>
	public interface IWebBagHolder
	{
		// attributes to get and set stored values
		// name-value pairs
		#region Attributes
		/// <summary>
		/// Get/Set values from integer key
		/// </summary>
		object this[ int index ]
		{
			get;
			set;
		}
		/// <summary>
		/// Get/Set values from string key
		/// </summary>
		object this[ string index ]
		{
			get;
			set;
		}

		#endregion

	} // end of IWebBagHolder

	//
	// These are the current concrete bag holders for the data.
	// 
	// 
	#region Cookie Bag
	/////////////////////////////////////////////////////////////////////////
	/// <summary>
	///  This class utilizes cookies to store the data
	///  Encryption was not added though and may not be complete
	/// </summary>
	/// /////////////////////////////////////////////////////////////////////////
	public class CookieBag : IWebBagHolder
	{
		static CookieBag()
		{
			
		}
		///	<summary>
		///	Default property for accessing resources
		/// <param name="index">
		/// Index for the desired resource</param>
		/// <returns>
		/// Resource string value</returns>
		///</summary>

		public object this[ int index ]
		{
			get 
			{
				HttpCookie cookie= (HttpCookie)CookieUtil.Retrieve(index);
				if ( cookie != null )
					return cookie.Value;
				return null;
			}
			set
			{
				lock(this)
				{
					CookieUtil.Add(index,value);				
				}
			}
		} // endof this[string]

		/// <summary>
		/// Get Data Value
		/// </summary>
		public object this[ string index ]
		{
			get 
			{
				HttpCookie cookie= (HttpCookie)CookieUtil.Retrieve(index);
				if ( cookie != null )
					return cookie.Value;
				return null;
			}
			set
			{
				lock(this) 
				{
					CookieUtil.Add(index,value);							
				}
			}
		} // endof this[int]

	} // end of cookiebag

	#endregion

	#region Session Bag

	/////////////////////////////////////////////////////////////////////////
	///
	/// <summary>
	/// The Session bag will attempt to use server-side Session Mgmt. However
	/// in the event session is disabled fallback to cookies; otherwise, fallback
	/// to the database :(
	/// </summary>
	//////////////////////////////////////////////////////////////////////////
	public class SessionBag : IWebBagHolder
	{
		static SessionBag()
		{
			
		}
		///	<summary>
		///	Default property for accessing resources
		/// <param name="index">
		/// Index for the desired resource</param>
		/// <returns>
		/// Resource string value</returns>
		///</summary>

		public object this[ int index ]
		{
			get 
			{
				object obj = null;
				try 
				{
					// session state enabled
					if ( HttpContext.Current.Session != null)
						obj=HttpContext.Current.Session[index];
				}
				catch 
				{
					obj=null;
				}
				return obj;
			}
			set
			{
				try 
				{
					// session state enabled
					if ( HttpContext.Current.Session != null)
						HttpContext.Current.Session[index] = value;
				} 
				catch 
				{					
				}
				
			}
		}
		/// <summary>
		/// get data back
		/// </summary>
		public object this[ string index ]
		{
			get 
			{
				object obj = null;
				try 
				{
					// session state  enabled
					if ( HttpContext.Current.Session != null)
						obj=HttpContext.Current.Session[index];
				}
				catch {
					obj=null;
				}
				return obj;
			}
			set
			{
				try 
				{
					// session state  enabled
					if ( HttpContext.Current.Session != null)
						HttpContext.Current.Session[index] = value;
				} 
				catch 
				{
						
				}				
			}
		}
	} // end of SessionBag

	#endregion

	#region Application Bag

	/////////////////////////////////////////////////////////////////////////
	/// <summary>
	/// The Application bag will attempt to use server-side Application Mgmt.
	/// This is the fallback. The database could also be a fallback as well
	/// but then anonnymous user information would be logged there as well which
	/// I don't you would want
	/// </summary>
	/////////////////////////////////////////////////////////////////////////
	public class ApplicationBag : IWebBagHolder
	{
		static ApplicationBag()
		{
			
		}
		///	<summary>
		///	Default property for accessing resources
		/// <param name="index">
		/// Index for the desired resource</param>
		/// <returns>
		/// Resource string value</returns>
		///</summary>

		public object this[ int index ]
		{
			get 
			{
				return HttpContext.Current.Application.Get(index);
			}
			set
			{
				HttpContext.Current.Application.Lock();
				HttpContext.Current.Application.Add(index.ToString(),value);
				HttpContext.Current.Application.UnLock();
			}
		}
		/// <summary>
		/// Get data value
		/// </summary>
		public object this[ string index ]
		{
			get 
			{
				return HttpContext.Current.Application.Get(index);
			}
			set
			{
				HttpContext.Current.Application.Lock();
				HttpContext.Current.Application.Add(index,value);
				HttpContext.Current.Application.UnLock();
			}
		}
	} // end of ApplicationBag
	
	#endregion

	//////////////////////////////////////////////////////////////////////
	/// <summary>
	/// This singleton factory creates the appropriate Bag for a user to hold data
	/// The data retention mechanism varies.
	/// </summary>
	/// //////////////////////////////////////////////////////////////////////
	public sealed class BagFactory 
	{		
		// valid bag types
		public enum BagFactoryType
		{
			ApplicationType = 1,
			SessionType		= 2,
			CookieType		= 3,
			DbType			= 4,
		}
		// the singleton class instance (ONLY ONE -- APPLICATION LEVEL )
		public static readonly BagFactory instance = new BagFactory();
	
		/// <summary>
		/// Create the Bag according to what is available. First use Cookies,
		/// then try Session and then fallback to Application.
		/// </summary>
		public IWebBagHolder create ()
		{
		
			// if no session, use cookies
			if ( HttpContext.Current.Session == null  )
				return new CookieBag();
			// using a session
			else if ( System.Web.SessionState.SessionStateMode.InProc == HttpContext.Current.Session.Mode )
				// use the session
				return new SessionBag();

			// get the default bag
			return new ApplicationBag();

		} // end of create

		/// <summary>
		/// Create the Bag according to what is available. First use Cookies,
		/// then try Session and then fallback to Application.
		/// </summary>
		public IWebBagHolder create (BagFactoryType bag_type)
		{
			// application type
			if ( bag_type == BagFactoryType.ApplicationType )
				// get the appli. bag
				return new ApplicationBag();
			// session type
			else if ( bag_type == BagFactoryType.SessionType &&
				// if session is not available, then use the default
				 HttpContext.Current.Session != null)
				return new SessionBag();
			// cookie type
			else if ( bag_type == BagFactoryType.CookieType )
				return new CookieBag();

			// get the default bag
			return new ApplicationBag();

		} // end of create

		// don't allow for construction outside of this class
		private BagFactory() {}
	
	}
}
